package com.mapbased.wfw.components;

import java.io.*;

import org.dom4j.*;
import com.mapbased.wfw.*;
import java.util.Map;
import java.util.Collection;
import java.util.List;
import com.mapbased.wfw.PageLoader.StringBufferBag;
import com.mapbased.wfw.PageLoader.LoadContext;
import com.mapbased.da.FeatureMeta;
import com.mapbased.cc.SpringAppContext;
import org.springframework.context.ApplicationContext;
import com.mapbased.da.MetaFactory;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2004</p>
 *
 * <p>Company: mapbased.com</p>
 *
 * @author chy(Baily)
 * @version 1.0
 */
public class Repeat
    extends Component
{
    public static final String ComponentName="repeat";

    public static final String AN_DataSource="data";

    public static final String AN_ItemVar="itemvar";

    public static final String AN_IndexVar="indexvar";

    public static final String AN_RemoveTag="removetag";
    private Binding dataSource;
    private FeatureMeta featureMeta;
    private String itemVarName="Repeat_item";
    private String indexVarName;
    public Repeat()
    {
        super();
    }

    public void renderHeader(RenderContext context,StringBuffer sb,Map m)
    {}

    /**
     * render
     *
     * @param context RenderContext
     * @throws IOException
     * @todo Implement this com.mapbased.wfw.Component method
     */
    public void render(RenderContext context)
        throws IOException
    {
        Object o=this.dataSource != null ? this.dataSource.getValue(context)
            : this.featureMeta.query(context.getRequestMap());
        if(o == null)
        {
            return;
        }
        if(o instanceof Object[])
        {
            Object[] os=(Object[])o;
            for(int i=0;i < os.length;i++)
            {
                inloop(os[i],i,context);
            }
            return;

        }
        java.util.Iterator i=null;

        if(o instanceof Collection)
        {
            i=((Collection)o).iterator();
        }
        else if(o instanceof Map)
        {
            i=((Map)o).entrySet().iterator();

        }
        else
        {
            try
            {
                i=(java.util.Iterator)o;
            }
            catch(java.lang.ClassCastException e)
            {
                throw new java.lang.ClassCastException("Try cast from:" +
                    o.getClass().getName()
                    + "to:Iterator,Object is:" + o);
            }
        }
        int ic=0;
        while(i.hasNext())
        {
            inloop(i.next(),ic,context);
            ic++;

        }

    }

    final private void inloop(Object item,int index,RenderContext context)
        throws IOException
    {
        Map m=context.getRequestMap();
        m.put(this.itemVarName,item);
        if(this.indexVarName != null)
        {
            m.put(this.indexVarName,new Integer(index));

        }
        this.defalutRenderBehavior(context);

    }

    public Element parseXml(Element ele,PageLoader.LoadContext loader)
    {
        Attribute item=ele.attribute(this.AN_ItemVar);
        if(item != null)
        {
            this.itemVarName=item.getValue().trim();
            ele.remove(item);
        }

        Attribute index=ele.attribute(this.AN_IndexVar);
        if(index != null)
        {
            this.indexVarName=index.getValue().trim();
            ele.remove(index);
        }
        Attribute removetag=ele.attribute(this.AN_RemoveTag);
        boolean remove=false;
        if(removetag != null)
        {
            if("true".equalsIgnoreCase(removetag.getValue().trim()))
            {
                remove=true;
            }
            ele.remove(removetag);
        }

        ///////////////////////////////////////////////////////////////
        Attribute a=ele.attribute("featureMeta");

        // String fm=ele.attributeValue("featureMeta");
        if(a == null)
        {
            a=ele.attribute("datasource");
        }
        if(a != null)
        {
            String fm=a.getValue();
            ele.remove(a);
            ApplicationContext ac=((SpringAppContext)loader.loader.getGlobal().
                                   getAppContext()).getApplicationContext();

            int dindex=fm.indexOf('.');
            String metafactory=fm.substring(0,dindex).trim();
            String fmeta=fm.substring(dindex + 1).trim();

            MetaFactory metaFactory=
                (MetaFactory)ac.getBean(metafactory);
            if(metaFactory == null)
            {
                throw new java.lang.NullPointerException(
                    "Cannot find MetaFactory:" + metafactory);
            }
            this.featureMeta=metaFactory.get(fmeta);
            if(this.featureMeta == null)
            {
                throw new java.lang.NullPointerException(
                    "Cannot find FeatureMeta:" + fmeta);
            }
            if(remove)
            {
                LoadContext nlc=new LoadContext(loader);

                nlc=new LoadContext(loader);
                loader.loader.parseElementChildren(ele,nlc);
                nlc.finish();
                this.segments=nlc.segments.toArray();

                return null;

            }
            else
            {
                return ele;
            }

        }
////////////////////////////////////////////////////////////////////////////////
        a=ele.attribute(this.AN_DataSource);
        if(a == null)
        {
            throw new java.lang.RuntimeException(
                "Cannot find data attribute for repeat:" +
                ele.getName());
        }
        String s=a.getValue();
        ele.remove(a);

        LoadContext nlc=new LoadContext(loader);
        List l=nlc.segments;

        loader.loader.parseBinding(s,nlc);
        for(int i=0;i < l.size();i++)
        {
            Object o=l.get(i);
            if(o instanceof Binding)
            {
                this.dataSource=(Binding)o;
                if(remove)
                {
                    nlc=new LoadContext(loader);
                    loader.loader.parseElementChildren(ele,nlc);
                    nlc.finish();
                    this.segments=nlc.segments.toArray();

                    return null;

                }
                else
                {
                    return ele;
                }
            }
        }
        throw new java.lang.RuntimeException("Cannot find binding for repeat:" +
                                             ele.getName());

    }

    public void setDataSource(Binding dataSource)
    {
        this.dataSource=dataSource;
    }

    public void setItemVarName(String itemVarName)
    {
        this.itemVarName=itemVarName;
    }

    public void setIndexVarName(String indexVarName)
    {
        this.indexVarName=indexVarName;
    }

    public Binding getDataSource()
    {
        return dataSource;
    }

    public String getItemVarName()
    {
        return itemVarName;
    }

    public String getIndexVarName()
    {
        return indexVarName;
    }
}
